package com.dlc.apk.utils.soundAnimation

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.util.AttributeSet
import android.util.Log
import android.view.View
import com.dlc.apk.R
import java.util.*


class LineLoadingView(context: Context, attrs: AttributeSet?) : View(context, attrs) {
    private val TAG = "MusicLoadingView"
    private var paint: Paint? = null
    private var rectF: RectF? = null
    var isPlaying = false
        private set

    //属性
    private var lineSpace //两条线之间的宽度
            = 0
    private var changeStep //动画幅度
            = 0f
    private var lineCount //堆数，每堆5根线条
            = 0
    private var lineWidth //线宽度
            = 0
    private var changeSpeed //变化速度  次/秒
            = 0
    private var color //颜色
            = 0
    private var mWidth //dp
            = 0
    private var maxHeight //最高高度
            = 0
    private var minHeight //最低高度
            = 0
    private var radius //线条弧度
            = 0f

    //draw用到的中间参数
    private var tempHeight = 0 //
    private var minTempHeight //最低线条的高度记录(0,4)
            = 0
    private var minLowing = false
    private var middleTempHeight //中等高度线条的高度记录（1,3）
            = 0
    private var middleLowing = false
    private var maxTempHeight //最高线条的高度记录（2）
            = 0
    private var maxLowing = false
    private val minList: MutableList<Int> = ArrayList()
    private val middleList: MutableList<Int> = ArrayList()
    private val maxList: MutableList<Int> = ArrayList()
    private var runnable: Runnable? = null
    fun startAnim() {
        if (!isPlaying) {
            isPlaying = true
            if (runnable == null) {
                runnable = Runnable {
                    while (isPlaying) {
                        rectF?.left = 0f //复用这个rectF，每次动画重置初始值
                        rectF?.right = lineWidth.toFloat()
                        postInvalidate()
                        try {
                            Thread.sleep((1000 / changeSpeed).toLong()) //控制速度
                        } catch (e: InterruptedException) {
                            e.printStackTrace()
                        }
                    }
                }
            }
            post { Thread(runnable).start() }
        }
    }

    fun pauseAnim() {
        isPlaying = false
    }

    //停止动画时还原到初始状态
    fun stopAnim() {
        minTempHeight = minHeight
        minLowing = false
        middleTempHeight = (minHeight + maxHeight) / 2
        middleLowing = true
        maxTempHeight = maxHeight
        maxLowing = true
        isPlaying = false
        postInvalidate()
    }

    private fun init(typedArray: TypedArray) {
        lineCount = typedArray.getInteger(R.styleable.LineLoadingView_lineCount, 1) //默认1
        lineWidth = typedArray.getDimension(R.styleable.LineLoadingView_lineWidth, dip2px(3f).toFloat()).toInt() //默认3
        lineSpace = typedArray.getDimension(R.styleable.LineLoadingView_lineSpace, dip2px(7f).toFloat()).toInt() //默认7
        color = typedArray.getColor(R.styleable.LineLoadingView_lineColor, Color.parseColor("#FFFFE105"))
        maxHeight = typedArray.getDimension(R.styleable.LineLoadingView_lineMaxHeight, dip2px(50f).toFloat()).toInt()
        minHeight = typedArray.getDimension(R.styleable.LineLoadingView_lineMinHeight, dip2px(10f).toFloat()).toInt()
        changeStep = typedArray.getFloat(R.styleable.LineLoadingView_changeStep, 0.1f) * maxHeight //默认0.1
        changeSpeed = typedArray.getInt(R.styleable.LineLoadingView_changeSpeed, dip2px(6f))
        radius = typedArray.getDimension(R.styleable.LineLoadingView_lineRadius, dip2px(3f).toFloat())
        mWidth = lineCount * 4 * (lineSpace + lineWidth) + lineWidth
        minTempHeight = minHeight
        minLowing = false
        middleTempHeight = (minHeight + maxHeight) / 2
        middleLowing = true
        maxTempHeight = maxHeight
        maxLowing = true
        Log.i(TAG, "MusicLoadingView: " + lineCount
                + " 变化： " + changeStep
                + "  线宽： " + lineWidth
                + "  线空隙： " + lineSpace
                + "  高度：" + maxHeight
                + " 最低： " + minHeight
                + "  width:" + mWidth)
        paint = Paint()
        paint?.style = Paint.Style.FILL
        paint?.isAntiAlias = true
        paint?.color = color
        rectF = RectF()
        rectF?.left = 0f
        rectF?.right = lineWidth.toFloat()
        for (i in 0..lineCount * 4) {
            if (i % 4 == 0) {
                //min
                minList.add(i)
            } else if (i % 2 != 0) {
                //middle
                middleList.add(i)
            } else {
                //max
                maxList.add(i)
            }
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
        setMeasuredDimension(mWidth, maxHeight)
    }

    override fun onDraw(canvas: Canvas) {  //第0秒
        super.onDraw(canvas)
        //5个一组
        /**
         * 这里能看出来其实是有规律的
         * 可以进一步封装,来自定义有多少种不同高度的线条
         *
         * 有兴趣可以再进一步封装
         */
        //绘制最短线条
        minTempHeight = changeHeight(minTempHeight, minLowing) //改变高度
        minLowing = changeLowing(minTempHeight, minLowing) //改变逐增/逐减
        for (i in minList) {
            draw(canvas, i)
        }
        //绘制中等线条
        middleTempHeight = changeHeight(middleTempHeight, middleLowing)
        middleLowing = changeLowing(middleTempHeight, middleLowing)
        for (i in middleList) {
            draw(canvas, i)
        }
        //绘制最高线条
        maxTempHeight = changeHeight(maxTempHeight, maxLowing)
        maxLowing = changeLowing(maxTempHeight, maxLowing)
        for (i in maxList) {
            draw(canvas, i)
        }
    }

    //绘制，就是画一条竖线
    private fun draw(canvas: Canvas, i: Int) {  //i 标识位
        rectF!!.left = (i * (lineWidth + lineSpace)).toFloat()
        rectF!!.right = rectF!!.left + lineWidth
        val top = (maxHeight - tempHeight) / 2
        rectF!!.top = top.toFloat()
        rectF!!.bottom = (top + tempHeight).toFloat()
        canvas.drawRoundRect(rectF!!, radius, radius, paint!!)
    }

    /**
     * @param height 初始高度
     * @param lowing 减/增
     * @return 返回值要记录下来  作为下一次动画的初始高度
     */
    private fun changeHeight(height: Int, lowing: Boolean): Int {
        var height = height
        height = if (lowing) {
            //逐减中  按照changeStep进行逐减
            Math.max(height - changeStep, minHeight.toFloat()).toInt()
        } else {
            //逐增
            Math.min(height + changeStep, maxHeight.toFloat()).toInt()
        }
        tempHeight = height
        return height
    }

    private fun changeLowing(height: Int, lowing: Boolean): Boolean {
        var lowing = lowing
        if (lowing) {
            if (height <= minHeight) {  //减到最低了
                lowing = false //开始逐增
            }
        } else {
            if (height >= maxHeight) {  //增到最大了
                lowing = true //开始逐渐减少
            }
        }
        return lowing
    }

    fun dip2px(dipValue: Float): Int {
        val scale = context.resources.displayMetrics.density
        return (dipValue * scale + 0.5f).toInt()
    }

    init {
        val typedArray = context.obtainStyledAttributes(attrs, R.styleable.LineLoadingView)
        init(typedArray)
    }
}